package models;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;

import controllers.Ideas;

import play.data.validation.Required;
import play.db.jpa.Model;

@Entity
public class Item extends Model {

	// Name of the item
	@Required
	private String name;

	// Content is the description of the item, with specific time & date Author:
	// Youssef Selim
	@Required
	private String content;
	@Required
	private Date dateAndTime;

	// whether the item is completed or not, Author: Omar Hassab
	@Required
	private boolean completed;

	// Item associated to which plan Author: Youssef Selim
	@Required
	@ManyToOne
	private Plan plan;

	// Entity related to the item Author: Youssef Selim
	@Required
	@ManyToOne
	private Eentity entity;

	// Topic related to the item Author: Youssef Selim
	@Required
	@ManyToOne
	private Topic topic;

	// Users working on a certain item Author: Youssef Selim
	@Required
	@ManyToMany
	private List<User> users;

	// Collection of tags items are tagged by Author: Youssef Selim
	@ManyToMany
	private List<Tag> tags;

	// Item Constructor Author: Youssef Selim
	// Modified Constructor : Andrew Guirguis
	public Item(String name, String content, Date d, Plan plan) {
		this.setPlan(plan);
		this.setName(name);
		this.setContent(content);
		this.setDateAndTime(d);
		this.setUsers(new LinkedList<User>());
		this.setTags(new LinkedList<Tag>());
	}

	/**
	 * Setter for Content
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @param content
	 *            : the content to set
	 */
	public void setContent(String content) {
		this.content = content;
	}

	/**
	 * Getter for Content
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @return the content
	 */
	public String getContent() {
		return content;
	}

	/**
	 * Setter for Date & Time
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @param date
	 *            : the date to set
	 */
	public void setDateAndTime(Date dateAndTime) {
		this.dateAndTime = dateAndTime;
	}

	/**
	 * Getter for Date
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @return the date
	 */
	public Date getDateAndTime() {
		return dateAndTime;
	}

	/**
	 * Setter for Plan
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @param plan
	 *            : the plan to set
	 */
	public void setPlan(Plan plan) {
		this.plan = plan;
	}

	/**
	 * Getter for Plan
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @return the plan
	 */
	public Plan getPlan() {
		return plan;
	}

	/**
	 * Setter for Entity
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @param entity
	 *            : the entity to set
	 */
	public void setEntity(Eentity entity) {
		this.entity = entity;
	}

	/**
	 * Getter for Entity
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @return the entity
	 */
	public Eentity getEntity() {
		return entity;
	}

	/**
	 * Setter for Topic
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @param topic
	 *            : the topic to set
	 */
	public void setTopic(Topic topic) {
		this.topic = topic;
	}

	/**
	 * Getter for Topic
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @return the topic
	 */
	public Topic getTopic() {
		return topic;
	}

	/**
	 * Setter for Users
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @param users
	 *            : the users to set
	 */
	public void setUsers(List<User> users) {
		if (this.plan.getDiff(this.users, users) != "")
			this.plan.getTimeline().add(
					"Date: " + this.plan.getDate().toString() + " | Item :"
							+ this.name + " User/s changes: "
							+ this.plan.getDiff(this.users, users));
		this.users = users;

	}

	/**
	 * Getter for Users
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @return the users
	 */
	public List<User> getUsers() {
		return users;
	}

	/**
	 * Setter for Tags
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @param tags
	 *            : the tags to set
	 */
	public void setTags(List<Tag> tags) {
		this.tags = tags;
	}

	/**
	 * Getter for Tags
	 * 
	 * @author Youssef Selim
	 * @version 2011.0425
	 * @return the tags
	 */
	public List<Tag> getTags() {
		return tags;
	}

	/**
	 * Setter for Name
	 * 
	 * @author Andrew Guirguis
	 * @version 2011.0429
	 * @param name
	 *            : the name to set
	 * 
	 * */

	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Getter for Name
	 * 
	 * @author Andrew Guirguis
	 * @version 2011.0429
	 * @return the name of the item
	 */
	public String getName() {
		return name;
	}

	/**
	 * Overrides toString method, and return the name of the item
	 * 
	 * @author Youssef Selim
	 * @version 2011.0501
	 * @return the item name
	 */
	public String toString() {
		return name;
	}

	/**
	 * sets a new value to completed
	 * 
	 * @author Omar Hassab
	 * @version 2011.0503
	 * @param new value for completed
	 */
	public void setCompleted(boolean completed) {
		this.completed = completed;
	}

	/**
	 * gets the value of completed
	 * 
	 * @author Omar Hassab
	 * @version 2011.0503
	 * @return value for completed
	 */
	public boolean isCompleted() {
		return completed;
	}

	public void addUser(User user) {
		if(!users.contains(user)) {
			users.add(user);
			user.addItem(this);
		}
	}

	public void addTag(Tag tag) {
		if (!tags.contains(tag)) {
			tags.add(tag);
			tag.addItem(this);
		}
	}
}
